#pragma once

#include <string>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <nlohmann/json.hpp>
#include <cppjieba/Jieba.hpp>
#include <unordered_map>
#include <fstream>
#include "Document.h"

using std::streamoff;
using std::unordered_map;
using std::string;
using std::set;
using std::map;
using std::vector;
using std::pair;
using std::list;

//LRU缓存结构
class LRUCache{
public:
    LRUCache(int capacity):m_capacity(capacity)
    {}

    int get(int key);
private:
    int m_capacity;
};

class QueryEngine{
public:
    static QueryEngine& getInstance();

    nlohmann::json KeyRecommander(const string& keyword);
    nlohmann::json WebPageSearcher(const string& query);

private:
    QueryEngine();
    ~QueryEngine() = default; 

    QueryEngine(const QueryEngine&) = delete;
    QueryEngine& operator=(const QueryEngine&) = delete;
    
private:
    //计算两个序列之间的编辑距离
    template<typename Sequence>
    static int editDistance(Sequence seq1, Sequence seq2);

    //进行优先级选择的结构体
    struct Pri{
        string word;
        int length;
        int frequency;
    };

    // 字符串转streamoff类型
    streamoff string_to_streamoff(const string& str_offset);

private:
    // 成员变量保持不变
    cppjieba::Jieba m_tokenizer;
    // 停用词集合
    set<string> m_stopWords;
    // 词典: 单词-词频
    vector<pair<string,int>> m_dict;
    // 首字符-索引
    map<string,set<int>> m_index;
    // 倒排索引
    map<string,map<int,double>> m_invertedIndex;
    // 文档总数
    int m_N;
    // 网页偏移量
    unordered_map<string, vector<streamoff>> m_offset;

};